// spoj375
// run: $exec < input
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>

int const inf = 1 << 27;
int const maxn = 20007;
int parent[maxn];
int depth[maxn];
int size[maxn];

int top[maxn];
int tid[maxn]; // edge index after hld
int id[maxn];  // edge index before hld
int heavy_son[maxn];

int end_point[maxn];
int weight[maxn];
int next[maxn];
int head[maxn];

int cost[maxn];
int edge_alloc, n, dfs_tick;

int seg_tree[4 * maxn];

void init()
{
	edge_alloc = 2;
	std::memset(head, 0, sizeof(head));
}

void add_edge(int u, int v, int c)
{
	end_point[edge_alloc] = v; weight[edge_alloc] = c; next[edge_alloc] = head[u]; head[u] = edge_alloc++;
	end_point[edge_alloc] = u; weight[edge_alloc] = c; next[edge_alloc] = head[v]; head[v] = edge_alloc++;
}

void dfs_size(int u, int p, int d)
{
	parent[u] = p;
	depth[u] = d;
	size[u] = 1;
	heavy_son[u] = 0;
	int max_size = 0;
	for (int i = head[u]; i; i = next[i]) {
		int v = end_point[i];
		if (v == p) continue;
		cost[v] = weight[i];
		dfs_size(v, u, d + 1);
		size[u] += size[v];
		if (size[v] > max_size) {
			max_size = size[v];
			heavy_son[u] = v;
		}
	}
}

void seg_interval_max_update(int id, int il, int ir, int l, int r, int val) // il means interval l, same as ir
{
	if (l <= il && ir <= r) seg_tree[id] = val;
	else {
		int tl = 2 * id, tr = tl ^ 1;
		int mid = (il + ir) / 2;
		if (l <= mid)
			seg_interval_max_update(tl, il, mid, l, r, val);
		if (mid < r)
			seg_interval_max_update(tr, mid + 1, ir, l, r, val);
		seg_tree[id] = std::max(seg_tree[tl], seg_tree[tr]);
	}
}

int seg_query(int id, int il, int ir, int l, int r)
{
	if (l <= il && ir <= r) return seg_tree[id];
	else {
		int tl = id * 2, tr = tl ^ 1;
		int mid = (il + ir) / 2, ret = 0;
		if (l <= mid) ret = std::max(ret, seg_query(tl, il, mid, l, r));
		if (mid < r) ret = std::max(ret, seg_query(tr, mid + 1, ir, l, r));
		return ret;
	}
}

void seg_update(int id, int val)
{
	int u = end_point[id], v = end_point[id ^ 1];
	if (parent[u] == v) std::swap(u, v);
	seg_interval_max_update(1, 1, n, tid[v], tid[v], val);
}

int query(int u, int v)
{
	int ret = 0;
	while (top[u] != top[v]) {
		if (depth[top[u]] < depth[top[v]]) std::swap(u, v);
		ret = std::max(ret, seg_query(1, 1, n, tid[top[u]], tid[u]));
		u = parent[top[u]];
	}
	if (depth[u] > depth[v]) std::swap(u, v);
	ret = std::max(ret, seg_query(1, 1, n, tid[u] + 1, tid[v]));
	return ret;
}

void dfs_heavy_chain(int u, int ancestor)
{
	tid[u] = ++dfs_tick;
	top[u] = ancestor;
	seg_interval_max_update(1, 1, n, tid[u], tid[u], cost[u]);
	if (heavy_son[u]) dfs_heavy_chain(heavy_son[u], ancestor);
	for (int i = head[u]; i; i = next[i]) {
		int v = end_point[i];
		if (v == parent[u] || v == heavy_son[u]) continue;
		dfs_heavy_chain(v, v);
	}
}

int main()
{
	int T;
	std::scanf("%d", &T);
	while (T--) {
		std::scanf("%d", &n);
		init();
		for (int i = 1, x, y, z; i < n; i++) {
			std::scanf("%d %d %d", &x, &y, &z);
			id[i] = edge_alloc;
			add_edge(x, y, z);
		}

		std::memset(seg_tree, 0, sizeof(seg_tree));
		dfs_size(1, 0, 0);
		cost[1] = -inf;
		dfs_tick = 0;
		dfs_heavy_chain(1, 1);

		char s[10];
		while (std::scanf("%s", s) && s[0] != 'D') {
			int x, y;
			std::scanf("%d %d", &x, &y);
			if (s[0] == 'C') seg_update(id[x], y);
			else			 std::printf("%d\n", query(x, y));
		}
	}
}

